﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace CSharpWheels.Librarys
{

    #region 

    //一、RuntimeHelpers.PrepareConstrainedRegions() 是.NET 中用于创建受限执行区域(Constrained Execution Region, CER)的关键方法，
    //它通过预先准备关键代码来确保在极端条件下(如低内存、线程中止等)代码仍能可靠执行。
    //核心作用:
    //1.预先编译(JIT)代码：

    //强制CLR在执行前预先JIT编译try块和finally块中的所有代码

    //避免执行时因内存不足导致JIT编译失败

    //2.防止异步线程中止：

    //在CER区域内，CLR会阻止Thread.Abort() 中断代码执行

    //确保关键清理代码能够完整执行

    //3.提前内存分配：

    //预先分配方法可能需要的所有内存

    //避免执行时因内存不足导致分配失败
    internal class CER
    {
        //1.非托管资源释放
        //[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        //private static void SafeRelease(IntPtr handle)
        //{
        //    RuntimeHelpers.PrepareConstrainedRegions();
        //    try { }
        //    finally
        //    {
        //        if (handle != IntPtr.Zero)
        //        {
        //            NativeMethods.CloseHandle(handle);
        //        }
        //    }
        //}

        //2.关键状态变更
        private bool _criticalFlag;

        public void SetCriticalFlag(bool value)
        {
            RuntimeHelpers.PrepareConstrainedRegions();
            try { }
            finally
            {
                _criticalFlag = value; // 保证状态一定会被设置
            }
        }
    }


    /// <summary>
    /// 实际示例：安全句柄实现
    /// </summary>
    public class SafeDatabaseHandle : CriticalFinalizerObject, IDisposable
    {
        private IntPtr _handle;

        [DllImport("dbapi.dll")]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        private static extern IntPtr OpenDatabase(string connectionString);

        [DllImport("dbapi.dll")]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        private static extern void CloseDatabase(IntPtr handle);

        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        public SafeDatabaseHandle(string connectionString)
        {
            RuntimeHelpers.PrepareConstrainedRegions();
            try { }
            finally
            {
                _handle = OpenDatabase(connectionString);
                if (_handle == IntPtr.Zero)
                    throw new Exception("Failed to open database");
            }
        }

        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        ~SafeDatabaseHandle()
        {
            Dispose(false);
        }

        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        protected virtual void Dispose(bool disposing)
        {
            RuntimeHelpers.PrepareConstrainedRegions();
            try { }
            finally
            {
                if (_handle != IntPtr.Zero)
                {
                    CloseDatabase(_handle);
                    _handle = IntPtr.Zero;
                }
            }
        }
    }

    #endregion

    #region 
    //二、RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup() 是.NET 中一个高级方法，用于确保即使在极端情况下（如栈溢出、线程中止或内存不足）也能执行清理代码。
    //它是 CER (Constrained Execution Region) 机制的一部分。

    class ExecuteCodeWithGuaranteedCleanupDemo
    {
        static void Demo()
        {
            var resource = new CriticalResource();

            RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(
                userData =>
                {
                    // 主执行代码
                    var res = (CriticalResource)userData;
                    res.DoSomethingCritical();
                },
                (userData, exceptionThrown) =>
                {
                    // 清理代码（无论是否发生异常都会执行）
                    var res = (CriticalResource)userData;
                    res.Cleanup();

                    if (exceptionThrown)
                    {
                        Console.WriteLine("执行过程中发生了异常");
                    }
                },
                resource);
        }
    }

    class CriticalResource
    {
        public void DoSomethingCritical()
        {
            Console.WriteLine("执行关键操作...");
            // 可能抛出异常的操作
        }

        public void Cleanup()
        {
            Console.WriteLine("执行清理操作...");
        }
    }
    #endregion

    #region

    //三、 CriticalFinalizerObject 是.NET 中一个特殊基类，用于创建具有高可靠性终结器的对象，确保即使在应用程序域卸载或低内存情况下也能执行资源清理。

    public class SafeFileHandle : CriticalFinalizerObject, IDisposable
    {
        private IntPtr _handle;

        // 构造函数
        public SafeFileHandle(IntPtr handle)
        {
            _handle = handle;
        }

        // 终结器（自动提升为关键终结器）
        ~SafeFileHandle()
        {
            Dispose(false);
        }

        // IDisposable 实现
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (_handle != IntPtr.Zero)
            {
                CloseHandle(_handle);
                _handle = IntPtr.Zero;
            }
        }

        [DllImport("kernel32.dll", SetLastError = true)]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        private static extern bool CloseHandle(IntPtr handle);
    }

    #endregion

}
